package servlet;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import entities.Game;
import entities.User;
import fachlogik.UserHome;

/** TODO Race Conditions beseitigen **/

public class ServletFL
{
	private List<RunningGame> aktuelleSpiele;
	private List<UserHome> angemeldeteUser;
	private List<User> spielsuchendeUser;
	private DatabaseAccess persistence;

	public ServletFL()
	{
		aktuelleSpiele = new ArrayList<RunningGame>();
		angemeldeteUser = new ArrayList<UserHome>();
		spielsuchendeUser = new ArrayList<User>();
		persistence = new DatabaseAccess();
	}

	public List<RunningGame> getAktuelleSpiele()
	{
		return aktuelleSpiele;
	}

	public List<UserHome> getAngemeldeteUser()
	{
		return angemeldeteUser;
	}

	public List<User> getAlleUser()
	{
		return persistence.getAlleUser();
	}

	public void neuerUser(String name, String pwd)
	{
		User u = new User();
		u.setName(name);
		u.setPassword(pwd);
		u.setRanking(0);
		persistence.speichern(u);
	}

	public void spielBeenden(User sieger, User verlierer)
	{
		Game g = new Game();
		g.setWon(sieger);
		g.setLost(verlierer);
		g.setId(0);

		double newWonElo = sieger.getRanking() + 10
				* (1 - elo(verlierer, sieger));
		double newLostElo = verlierer.getRanking() + 10
				* (0 - elo(sieger, verlierer));
		if (newLostElo < 0)
			newLostElo = 0;
		sieger.setRanking((int) newWonElo);
		verlierer.setRanking((int) newLostElo);

		persistence.speichern(g);
		persistence.speichern(sieger);
		persistence.speichern(verlierer);
	}

	public void setGewonnen(RunningGame r, char g)
	{
		r.setGewonnen(g);
	}

	public void spielEntfernen(RunningGame r)
	{
		aktuelleSpiele.remove(r);
	}

	private double elo(User a, User b)
	{
		return 1 / (1 + Math.pow(10,
				((double) (a.getRanking() - b.getRanking()) / (double) 400)));
	}

	public List<String> getRanking()
	{
		List<String> liste = new ArrayList<String>();
		for (User u : persistence.getRanking())
		{
			liste.add(u.getRanking() + " " + u.getName());
		}
		return liste;
	}

	public String getRankingString()
	{
		String ranking = "";
		List<String> liste = getRanking();
		for (int i = liste.size() - 1; i >= 0; i--)
		{
			if (i < 100)
			{
				ranking = ranking + liste.get(i);
				if (i != 0)
					ranking = ranking + ",";
			}
		}
		return ranking;
	}

	public List<User> getSpielsuchendeUser()
	{
		return spielsuchendeUser;
	}

	public RunningGame sucheMitspieler(User user)
	{
		for (RunningGame r : aktuelleSpiele)
		{
			if (r.getSpielerS() == user || r.getSpielerW() == user)
				return r;
		}

		User mitspieler = null;
		if (user != null)
		{
			if (!spielsuchendeUser.contains(user))
				spielsuchendeUser.add(user);
			for (User u : spielsuchendeUser)
			{
				if (user != u)
				{
					if (mitspieler == null)
					{
						mitspieler = u;
					} else
					{
						if ((Math.abs(mitspieler.getRanking()
								- user.getRanking())) > (Math.abs(u
								.getRanking() - user.getRanking())))
						{
							mitspieler = u;
						}
					}
				}
			}
		}

		if (mitspieler != null)
		{
			cancelMitspielerSuchen(mitspieler.getName());
			cancelMitspielerSuchen(user.getName());
			RunningGame r = new RunningGame();
			r.setSpielerS(mitspieler);
			r.setSpielerW(user);
			r.setAmZug('l');
			r.setGameState("bl1,wl2,bl3,wl4,b  ,w  ,b  ,w  ,wl2,bl3,wl4,b  "
					+ ",w  ,b  ,w  ,b  ,bl3,wl4,b  ,w  ,b  ,w  ,b  ,w  ,wl4"
					+ ",b  ,w  ,b  ,w  ,b  ,w  ,b  ,b  ,w  ,b  ,w  ,b  ,w  "
					+ ",b  ,wd4,w  ,b  ,w  ,b  ,w  ,b  ,wd4,bd3,b  ,w  ,b  "
					+ ",w  ,b  ,wd4,bd3,wd2,w  ,b  ,w  ,b  ,wd4,bd3,wd2,bd1");

			int i = 1;
			boolean vorhanden = false;
			while (r.getId() == 0)
			{
				vorhanden = false;
				for (RunningGame run : aktuelleSpiele)
				{
					if (run.getId() == i)
						vorhanden = true;
				}
				if (!vorhanden)
					r.setId(i);
				i++;
			}

			aktuelleSpiele.add(r);
			return r;
		}

		return null;
	}

	public void cancelMitspielerSuchen(String username)
	{
		List<User> templist = new ArrayList<>();
		for (User u : spielsuchendeUser)
		{
			if (username.equals(u.getName()))
				templist.add(u);
		}
		spielsuchendeUser.removeAll(templist);
	}

	public void userAnmelden(User u)
	{
		angemeldeteUser.add(new UserHome(u, new Date()));
	}
}
